jsx3.require("jsx3.gui.Block");
jsx3.require("com.gix.gui.LeftSelectButton");

/**
* A tabbed pane that uses a left-side selection area, instead of one at the top.  The "tabs" in this case are referred
* to as buttons, and are instances of the com.gix.gui.LeftSelectButton class.
**/
jsx3.Class.defineClass(
        "com.gix.gui.LeftSelectPane",
        jsx3.gui.Block,
        null,
        function (Pane, Pane_prototype) {

            /**
            * {String} The subject published to when one of this pane's buttons has been selected.  The published message will
            * include a field called <code>target</code> containing the button object that was selected.
            */
            Pane.BUTTON_SELECTED = "com.gix.gui.LeftSelectPane.BUTTON_SELECTED";

            /**
            * {com.gix.gui.LeftSelectButton} the currently selecred button
            * @private
            */
            Pane_prototype.selectedButton = null;

            /**
             * instance initializer
             * @param strName {String} unique name distinguishing this object from all other JSX GUI objects in the JSX application
             * @param vntLeft {int|String} either a number (i.e, 12, 30, etc) or a number and a unit value (i.e., "25%", "36pt", etc); if a number is passed, pixels will be the assumed unit when painted to screen
             * @param vntTop {int|String} either a number (i.e, 12, 30, etc) or a number and a unit value (i.e., "25%", "36pt", etc); if a number is passed, pixels will be the assumed unit when painted to screen
             * @param vntWidth {int|String} either a number (i.e, 12, 30, etc) or a number and a unit value (i.e., "25%", "36pt", etc); if a number is passed, pixels will be the assumed unit when painted to screen
             * @param vntHeight {int|String} either a number (i.e, 12, 30, etc) or a number and a unit value (i.e., "25%", "36pt", etc); if a number is passed, pixels will be the assumed unit when painted to screen
             * @param strHTML {String} Text/HTML markup to place in the jsx3.gui.Block instance
             * @param strLabel {String} the title label to place at the top left
             */
            Pane_prototype.init = function(strName, vntLeft, vntTop, vntWidth, vntHeight, strHTML, strLabel) {
                this.jsxsuper(strName, vntLeft, vntTop, vntWidth, vntHeight, strHTML);
                this.selectedButton = null;
                if(!strLabel) {
                    strLabel = "Label Text";
                }
                this.setDynamicProperty("jsxbgcolor", "-1");
                var firstLayout = new jsx3.gui.LayoutGrid("layout (--)", 0, 0, "100%", "100%");
                firstLayout.setRelativePosition(jsx3.gui.Block.ABSOLUTE).setDynamicProperty("jsxrows", "@addin@LeftSelectPane Layout1 Rows").setDynamicProperty("jsxcols", "@addin@LeftSelectPane Layout1 Cols");
                this.setChild(firstLayout, jsx3.app.Model.PERSISTEMBED, null, jsx3.app.Model.FRAGMENTNS);
                var block = new jsx3.gui.Block("block", 0, 0, "100%", "100%");
                block.setDynamicProperty("jsxpadding", "@addin@LeftSelectPane TopBlock Padding").setDynamicProperty("jsxoverflow", "@addin@LeftSelectPane TopBlock Overflow");
                firstLayout.setChild(block, jsx3.app.Model.PERSISTEMBED, null, jsx3.app.Model.FRAGMENTNS);
                var labelPane = new jsx3.gui.Block("lblSectionTitle", 0, 0, "100%", "100%", strLabel);
                labelPane.setDynamicProperty("jsxfontname", "@addin@LeftSelectPane Label Font Name").setDynamicProperty("jsxfontsize", "@addin@LeftSelectPane Label Font Size").setDynamicProperty("jsxfontweight", "@addin@LeftSelectPane Label Font Size").setDynamicProperty("jsxcolor", "@addin@LeftSelectPane Label Color").setDynamicProperty("jsxbgcolor", "@addin@LeftSelectPane Label BG Color").setDynamicProperty("jsxoverflow", "@addin@LeftSelectPane Label Overflow").setDynamicProperty("jsxtextalign", "@addin@LeftSelectPane Label Text Align").setDynamicProperty("jsxborder", "@addin@LeftSelectPane Label Border");
                block.setChild(labelPane, jsx3.app.Model.PERSISTEMBED, null, jsx3.app.Model.FRAGMENTNS);
                var lowerPane = new jsx3.gui.Block("lowerPane", 0, 0, "100%", "100%");
                lowerPane.setDynamicProperty("jsxoverflow", "@addin@LeftSelectPane LowerPane Overflow");
                firstLayout.setChild(lowerPane, jsx3.app.Model.PERSISTEMBED, null, jsx3.app.Model.FRAGMENTNS);
                var secondLayout = new jsx3.gui.LayoutGrid("layout (|)", 0, 0, "100%", "100%");
                secondLayout.setRelativePosition(jsx3.gui.Block.ABSOLUTE).setDynamicProperty("jsxcols", "@addin@LeftSelectPane Layout2 Cols").setDynamicProperty("jsxrows", "@addin@LeftSelectPane Layout2 Rows");
                lowerPane.setChild(secondLayout, jsx3.app.Model.PERSISTEMBED, null, jsx3.app.Model.FRAGMENTNS);
                var buttonPane = new com.gix.gui.LeftSelectPane.ButtonPane("buttonPane", 0, 0, "100%", "100%");
                buttonPane.setDynamicProperty("jsxoverflow", "@addin@LeftSelectPane ButtonPane Overflow");
                secondLayout.setChild(buttonPane, jsx3.app.Model.PERSISTEMBED, null, jsx3.app.Model.FRAGMENTNS);
                secondLayout.setChild(new jsx3.gui.Block("blkGutter", 0, 0, "100%", "100%"), jsx3.app.Model.PERSISTEMBED, null, jsx3.app.Model.FRAGMENTNS);
                secondLayout.setChild(new jsx3.gui.Block("contentPane", 0, 0, "100%", "100%"), jsx3.app.Model.PERSISTEMBED, null, jsx3.app.Model.FRAGMENTNS);
            };

            /**
            * Adds a new button to this LeftSelectPane.
            *
            * @param buttonText {String} the text label for the new button
            * @return {com.gix.gui.LeftSelectButton} the newly created child button
            */
            Pane_prototype.addButton = function(buttonText) {
                var button = new com.gix.gui.LeftSelectButton("button" + buttonText, 0, 0, null, buttonText);
                this.setChild(button, jsx3.app.Model.PERSISTEMBED);
                this.getButtonPane().repaint();
                if(button == this.selectedButton) {
                    this.getContentPane().repaint();
                    button.repaint();
                }
                return button;
            };

            /**
            * Sets the edit mode given child button (toggles the display of its edit icon)
            *
            * @param childButton {com.gix.gui.LeftSelectButton} the button to set the edit mode on
            * @param bEditMode {boolean} <code>true</code> puts the button in edit mode, <code>false</code> ends edit
            *                           mode
            */
            Pane_prototype.setEditMode = function(childButton, bEditMode) {
                if(childButton) {
                    childButton.setEditMode(bEditMode);
                }
            };

            /**
            * Convenience method to toggle the edit mode of the currently selected button, obvisting the need to
            * get a reference to, and pass in, the currently selected button.
            *
             * @param bEditMode {boolean} <code>true</code> puts the button in edit mode, <code>false</code> ends edit
             *                           mode
             */
            Pane_prototype.setSelectedEditMode = function(bEditMode) {
                this.setEditMode(this.selectedButton, bEditMode);
            };

            /**
            * Gets the currently selected button
            *
            * @return {com.gix.gui.LeftSelectButton} the currently selected button
            */
            Pane_prototype.getSelectedButton = function() {
                return this.selectedButton;
            }

            Pane_prototype.setChild = function(objChild, intPersist, strSourceURL, strNS) {
                if(objChild instanceof com.gix.gui.LeftSelectButton) {
                    return this.getButtonPane().setChild(objChild, intPersist, strSourceURL, strNS);
                }
                else {
                    if(this.getChildren().length == 0) {
                        return this.jsxsuper(objChild, intPersist, strSourceURL, strNS);
                    }
                    return false;
                }
            }

            /**
            * Upon the addition of a new button, this function adds the button's content pane to this container's content
            * pane.
            *
            * @private
            */
            Pane_prototype.buttonAdded = function(button) {
                var pane = this.getContentPane();
                var bPane = button.getContentPane();
                try {
                    pane.setChild(bPane.setRelativePosition(jsx3.gui.Block.ABSOLUTE), jsx3.app.Model.PERSISTNONE);
                }
                catch(ex) {
                    // do nothing, there is a harmless error here in some cases
                }
            }

            Pane_prototype.onSetChild = function(objChild) {
                if(!(objChild instanceof com.gix.gui.LeftSelectButton) && !(objChild instanceof jsx3.gui.Block)) return false;
                return this.jsxsuper(objChild);
            };

            /**
            * Sets the title text at the top left of this container.
            *
            * @param strText {String} the text to set as the title of this container
            */
            Pane_prototype.setLabelText = function(strText) {
                this.getLabelPane().setText(strText, true);
            };

            /**
            * Gets the label containing the title of this container.
            *
            * @return {jsx3.gui.Block} the title label for this container
            */
            Pane_prototype.getLabelPane = function() {
                try {
                    return this.getChild(0).getChild(0).getChild(0);
                }
                catch(ex) {
                    tibco.admin.Main.logException(ex);
                    return null;
                }
            }

            /**
            * Gets the pane containing all of the child buttons for this container.
            *
            * @return {com.gix.gui.LeftSelectPane.ButtonPane} the pane containing all of the child buttons for this container
            */
            Pane_prototype.getButtonPane = function() {
                return this.getChild(0).getChild(1).getChild(0).getChild(0);
            }

            /**
            * Gets the content pane of this container.  This content pane hosts the content panes for all of the individual
            * buttons.
            *
            * @return {jsx3.gui.Block} the content pane of this container
            */
            Pane_prototype.getContentPane = function() {
                return this.getChild(0).getChild(1).getChild(0).getChild(2);
            }

            /**
            * Handles the deselection of existing selected buttons if a new button is selected, and publishes a message
            * about the selection. To be called ONLY by the child button that has been selected!
            * @private
            */
            Pane_prototype.buttonSelected = function(buttonObj) {
                if(this.selectedButton == buttonObj) return;
                var prevButton = this.selectedButton;
                this.selectedButton = buttonObj;
                if(prevButton) {
                    prevButton.getContentPane().setDisplay(jsx3.gui.Block.DISPLAYNONE, true);
                    try {
                        prevButton.deselect();
                    }
                    catch(ex1) {
                        tibco.admin.Main.logException(ex1)
                    }
                }
                buttonObj.getContentPane().setDisplay(jsx3.gui.Block.DISPLAYBLOCK, true);
                this.getContentPane().repaint();
                var msg = new Object();
                msg.subject = com.gix.gui.LeftSelectPane.BUTTON_SELECTED;
                msg.target = buttonObj;
                try {
                    this.publish(msg);
                }
                catch(ex2) {
                    tibco.admin.Main.logException(ex2)
                }
            }

            Pane_prototype.onSetParent = function() {
                var ret = this.jsxsuper();
                this.setDynamicProperty("jsxbgcolor", "@Transparent BG");
                if(!this.selectedButton) {
                    var children = this.getButtonPane().getChildren();
                    for(var i = 0; i < children.length; i++) {
                        var child = children[i];
                        this.buttonAdded(child);
                    }
                }
                return ret;
            }

        });

/**
* The pane containing all of the buttons for a particular LeftSelectPane.
*/
jsx3.Class.defineClass(
        "com.gix.gui.LeftSelectPane.ButtonPane",
        jsx3.gui.Block,
        null,
        function (ButtonPane, ButtonPane_prototype) {
            ButtonPane_prototype.setChild = function(child, persist, source, ns) {
                if(child instanceof com.gix.gui.LeftSelectButton) {
                    var ret = this.jsxsuper(child, persist, source, ns);
                    var parent = this.getParent();
                    if(parent) {
                        parent = parent.getParent();
                        if(parent) {
                            parent = parent.getParent();
                            if(parent) {
                                parent = parent.getParent();
                            }
                        }
                    }
                    this.resetButtonBorders(parent);
                    if(parent) {
                        if(parent.buttonAdded) {
                            parent.buttonAdded(child);
                        }
                    }
                    return ret;
                }
                return false;
            };

            ButtonPane_prototype.onSetChild = function(child) {
                if(child instanceof com.gix.gui.LeftSelectButton) {
                    return this.jsxsuper(child);
                }
                else {
                    return false;
                }
            };

            ButtonPane_prototype.removeChild = function(vntItem) {
                var child = vntItem;
                if(!(child instanceof jsx3.app.Model)) {
                    child = this.getChild(child);
                }
                var parent = this.getParent();
                if(parent) {
                    parent = parent.getParent();
                    if(parent) {
                        parent = parent.getParent();
                        if(parent) {
                            parent = parent.getParent();
                            if(parent) {
                                if(parent.selectedButton == child) {
                                    parent.selectedButton = null;
                                }
                                parent.getContentPane().removeChild(child.getContentPane());
                            }
                        }
                    }
                }
                this.jsxsuper(vntItem);
                this.resetButtonBorders(parent);
                return this;
            }

            ButtonPane_prototype.removeChildren = function(arrChildren) {
                var parent = this.getParent();
                if(parent) {
                    parent = parent.getParent();
                    if(parent) {
                        parent = parent.getParent();
                        if(parent) {
                            parent = parent.getParent();
                            if(parent) {
                                for(var p = 0; p < arrChildren.length; p++) {
                                    var child = arrChildren[p];
                                    if(!(child instanceof jsx3.app.Model)) {
                                        child = this.getChild(child);
                                    }
                                    if(parent.selectedButton == child) {
                                        parent.selectedButton = null;
                                        break;
                                    }
                                    parent.getContentPane().removeChild(child.getContentPane());
                                }
                            }
                        }
                    }
                }
                this.jsxsuper(arrChildren);
                this.resetButtonBorders(parent);
                return this;
            }

            ButtonPane_prototype.onRemoveChild = function(objChild, index) {
                var parent = this.getParent();
                if(parent) {
                    parent = parent.getParent();
                    if(parent) {
                        parent = parent.getParent();
                        if(parent) {
                            parent = parent.getParent();
                        }
                    }
                }
                if(parent) {
                    if(objChild instanceof jsx3.app.Model) {
                        if(parent.selectedButton == objChild) {
                            parent.selectedButton = null;
                        }
                        parent.getContentPane().removeChild(objChild.getContentPane());
                    }
                    else {
                        for(var p = 0; p < objChild.length; p++) {
                            var child = objChild[p];
                            if(parent.selectedButton == child) {
                                parent.selectedButton = null;
                                break;
                            }
                            parent.getContentPane().removeChild(child.getContentPane());
                        }
                    }
                }
                this.jsxsuper();
                this.resetButtonBorders(parent);
                this.repaint();
            }

            /**
            * Iterates the child buttons and applies the proper border styles to them, based on their selection state.
            * Called anytime a new button has been added or removed fromthis pane.
            * @private
            */
            ButtonPane_prototype.resetButtonBorders = function(parent) {
                var children = this.getChildren();
                for(var i = 0; i < children.length; i++) {
                    var child = children[i];
                    if((i == 0) && parent && !parent.selectedButton) {
                        child.select();
                    }
                    if(i == 0) {
                        child.setDynamicProperty("jsxborder", "@addin@LeftSelectButton No Border");
                    }
                    else {
                        child.setDynamicProperty("jsxborder", "@addin@LeftSelectButton Border");
                    }
                }
            }

        });
